<template>
  <div class="chat-item answer-wrapper flex" @mouseover="showOpt = true" @mouseleave="showOpt = false">
    <div class="left-icon"><el-icon><IconRobot/></el-icon></div>
    <div class="answer-chat-wrapper flex">
      <div class="chat-content message-wrapper" @contextmenu="mousedown">
        <div class="message" v-if="content.message" ref="selectedNode">
          {{pMessage}}
        </div>
        <div class="message message-waiting" v-else>
          {{waitMessage}}
        </div>
      </div>
      <div class="opt-area flex ask-opt-area" v-show="showOpt">
        <div class="opt-btn" @click="copyTo('')">
          <el-icon><copy-icon></copy-icon></el-icon>
        </div>
        <div class="opt-btn" @click="reAnswer">
          <el-icon><reply-icon></reply-icon></el-icon>
        </div>
      </div>
    </div>
    <div class="opt-area" >
      <OptBtnMenu @close-menu="closeMenu" @menu-click="clickMenu" :buttons="menuButtons" v-show="showOptPlane" :menuStyle="menuStyle"></OptBtnMenu>
    </div>
  </div>
</template>

<script setup lang="ts">
import IconRobot from "@/components/icons/IconRobot.vue";
import {RIGHT_BUTTON} from "@/events/MouseEvent";
import CopyIcon from "@/components/icons/copyIcon.vue";
import DeleteIcon from "@/components/icons/deleteIcon.vue";
import {onUnmounted, reactive, type Ref, ref, watch} from "vue";
import LongerIcon from "@/components/icons/longerIcon.vue";
import ShorterIcon from "@/components/icons/shorterIcon.vue";
import SummaryIcon from "@/components/icons/summaryIcon.vue";
import OptBtnMenu from "@/components/OptBtnMenu.vue";
import {copy} from "@/utils/helper";
import {ElMessage} from "element-plus";
import ReplyIcon from "@/components/icons/ReplyIcon.vue";
import TranslateIcon from "@/components/icons/translateIcon.vue";
import {edit, reAnswerQa} from "@/apis/api";
import {socketListener} from "@/apis/socketIO";
const content = defineProps({
  message: {
    type: String,
    default: String('')
  },
  messageId: {
    default: String(''),
    type: String
  },
  qaId: {
    default: String(''),
    type: String
  }
});
const menuButtons = [{
  name: '文字加长',
  icon: LongerIcon,
  handle: ()=>{
    editMessage('LONG');
    closeMenu();
  }
}, {
  name: '文字变短',
  icon: ShorterIcon,
  handle: ()=>{
    editMessage('SHORT');
    closeMenu();
  }
}, {
  name: '文字总结',
  icon: SummaryIcon,
  handle: ()=>{
    editMessage('SUMMARY')
    closeMenu();
  }
},
  {
    name: '翻译',
    icon: TranslateIcon,
    handle: ()=>{
        editMessage('TRANSLATE', {
          from: "中文",
          to: "英文"
        })
      closeMenu();
    }
  }
  ,{
  name: '复制',
  icon: CopyIcon,
  handle: ()=>{
    let text: string = '';
    if (selectedSpan.value){
      const span = selectedSpan.value as HTMLSpanElement;
      text = span.innerText;
    }else{
      text = content.message ?? '';
    }
    copyTo(text);
    closeMenu();
  }
}
// ,{
//   name: '删除',
//   icon: DeleteIcon,
//   handle: (content: string)=>{
//     if (selectedSpan.value){
//        const span = selectedSpan.value as HTMLSpanElement;
//        span.innerText = '';
//     }
//     closeMenu();
//   }
// }
];

const reAnswer = () => {
  if(content.qaId) {
    reAnswerQa(content.qaId ?? '');
  }

};
const showOpt = ref(false);
const editMessage = (mode: string, options:any = {}) => {
  if(selectedSpan.value){
    const span = selectedSpan.value as HTMLSpanElement;
    if(span.innerText){
      edit(span.innerText, content.messageId??'', mode, options)
    }
  }
}
const menuStyle = reactive({
  left: '',
  top: ''
});
const copyTo = (text: string = '') => {
  copy(text ? text : content.message?content.message:'');
  //elMessage.success('复制成功');
  ElMessage({
    type: 'success',
    message: '复制成功'
  });
}
const clickMenu = (event: any) => {
  return event.handle();
}
const showOptPlane:Ref<Boolean> = ref<Boolean>(false);
const pMessage =ref('');
pMessage.value = content.message? content.message.toString() : '';
const tip = '思考中'
const waitMessage = ref('思考中');
const waitTime = 6;
let time = 0;
let waitStr = ''
const selectedNode = ref<HTMLElement|null>(null);
const selectionRef = ref<Selection | null>(null);
const selectedSpan = ref<HTMLElementTagNameMap['span']|HTMLElement | null>(null);

const mousedown = (e:any) => {
  if (e.button === RIGHT_BUTTON) {
    e.preventDefault();
    const node: HTMLElement|null = selectedNode.value
    var word:string = '';
    if (node) {
      if (document.getSelection()) {
        selectionRef.value = document.getSelection();
        setSelectionRange('rgb(156 191 239 / 57%)');
      }
    }
    showOptPlane.value = true;
    menuStyle.left = e.x + 'px';
    menuStyle.top = (e.y - 100) + 'px';
    e.stopPropagation();

  }
  return false;
}

const closeMenu = () =>{
  const span: HTMLElement = selectedSpan.value as HTMLElement;
  if (span){
    span.style.backgroundColor = '';
  }
  selectionRef.value = null;
  showOptPlane.value = false;
}
const setSelectionRange = (bg: string)=>{
  const span = document.createElement('span');
  span.style.backgroundColor = bg
  selectedSpan.value = span;
  const range = selectionRef.value?.getRangeAt(0);
  if(range){
    span.innerText = selectionRef.value ? selectionRef.value.toString() : '';
    selectionRef.value?.removeAllRanges();
    range.deleteContents();
    range.insertNode(span);
  }
}
let id:any = 0;
if(!content.message) {
  id = setInterval(() => {
    if (time < waitTime){
      time ++;
      waitStr += ' · ';
      waitMessage.value = tip + waitStr;
    }else{
      time = 0;
      waitStr = '';
      waitMessage.value = tip;
    }
  }, 800);
  onUnmounted(() => {
    waitMessage.value = '';
    clearInterval(id);
  });
}
const messageShow = (msg: string, start: number, end: number) =>{
  pMessage.value = msg.substring(start, end)
}
watch(() => content.message, (msg: string|undefined) => {
  if (msg){
    console.log('----------- msg change ------')
    waitMessage.value = '';
    clearInterval(id);
    waitStr = '';
    time = 0;
    let end: number = 0;
    const msgTimerId = setInterval(() => {
      if (end >= msg.length) {
        clearInterval(msgTimerId);
      }else{
        messageShow(msg, 0, end);
        end ++;
      }
    }, 100);
  }
})

socketListener('ReceiveEditMessage', 'chat')((data: any) => {
  // console.log(data);
  if (data['message_id'] === content.messageId) {
    console.log(data)
    if (selectedSpan.value) {
      const span = selectedSpan.value as HTMLSpanElement;
      span.innerText = data['message'];
    }
  }
});
</script>

<style lang="less" scoped>
.left-icon {
  width: 40px;
  height: 40px;
  font-size: 32px;
}
.answer-wrapper {
  .answer-chat-wrapper {
    width: calc(100% - 40px);
  }
  margin-top: 20px;
  margin-bottom: 30px;
  .message-wrapper{
    background: #F2F4F5;
    max-width: calc(100% - 80px);
    .message {
      white-space: pre-line;
    }
  }
}
</style>